UICollectionView 自适应高度获取

最后用 self.collectionView.collectionViewLayout.collectionViewContentSize.height 获取的高度是正确的

From: https://gxnotes.com/article/39898.html

问题描述

我有一个UICollectionViewUICollectionViewFlowLayout,我想计算其内容大小(为了通过AutoLayout调整其高度所需的intrinsicContentSize返回)。

问题是:即使我对所有单元都有一个固定和相等的高度,我也不知道在UICollectionView中有多少”rows” /线。由于表示数据项的单元格宽度不同,所以我也无法确定该数量的数量,因此UICollectionView的一行中的项目数量也会随之变化。

由于在官方文件中找不到关于这个主题的任何提示,谷歌搜索并没有给我带来任何进一步的帮助和想法,所以不会非常感激。

最佳解决方案

哇!由于某些原因,经过几个小时的研究,我现在发现了一个很简单的答案,我的问题是:我完全搜索错误的地方,挖掘所有可以在UICollectionView找到的文档。

简单易用的解决方案在于底层布局:只需在myCollectionView.collectionViewLayout属性上调用collectionViewContentSize即可获得内容的高度和宽度为CGSize。这样很简单。

次佳解决方案

如果您使用自动布局,则可以创建UICollectionView的子类

如果您使用下面的代码,那么您不必为集合视图指定任何高度约束,因为它将根据集合视图的内容而有所不同。

以下是实施:

@interface DynamicCollectionView : UICollectionView

@end

@implementation DynamicCollectionView

- (void) layoutSubviews
{
    [super layoutSubviews];

    if (!CGSizeEqualToSize(self.bounds.size, [self intrinsicContentSize]))
    {
        [self invalidateIntrinsicContentSize];
    }
}

- (CGSize)intrinsicContentSize
{
    CGSize intrinsicContentSize = self.contentSize;

    return intrinsicContentSize;
}

@end

第三种解决方案

viewDidAppear你可以得到它:

float height = self.myCollectionView.collectionViewLayout.collectionViewContentSize.height;

也许当你重新加载数据,然后需要用新的数据计算一个新的高度,然后你可以得到它:添加观察者监听,当你的CollectionView完成重新加载数据在viewdidload

[self.myCollectionView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionOld context:NULL];

然后添加波纹管功能获取新的高度或在collectionview完成重新加载后执行任何操作:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary  *)change context:(void *)context
{
    //Whatever you do here when the reloadData finished
    float newHeight = self.myCollectionView.collectionViewLayout.collectionViewContentSize.height;    
}

不要忘了删除观察者:

[self.myCollectionView removeObserver:self forKeyPath:@"contentSize" context:NULL];

第四种方案

user1046037在Swift中回答

class DynamicCollectionView: UICollectionView {
    override func layoutSubviews() {
        super.layoutSubviews()
        if bounds.size != intrinsicContentSize() {
            invalidateIntrinsicContentSize()
        }
    }

    override func intrinsicContentSize() -> CGSize {
        return self.contentSize
    }
}

第五种方案

用户1046037的Swift 3代码回答

import UIKit

class DynamicCollectionView: UICollectionView {

    override func layoutSubviews() {
        super.layoutSubviews()
        if !__CGSizeEqualToSize(bounds.size, self.intrinsicContentSize) {
            self.invalidateIntrinsicContentSize()
        }

    }

    override var intrinsicContentSize: CGSize {
        return contentSize
    }

}

参考文献

Author

陈昭

Posted on

2017-08-29

Updated on

2021-12-27

Licensed under

You need to set install_url to use ShareThis. Please set it in _config.yml.
You forgot to set the business or currency_code for Paypal. Please set it in _config.yml.

Kommentare

You forgot to set the shortname for Disqus. Please set it in _config.yml.